#pragma once

#include "../inc/ff_utils.h"

using namespace feifei;

class OclUtilsTest
{
private:
	int argc;
	char** argv;

public:
	void Test()
	{
		PrintSeperator('*');
		PrintHeader("opencl utils test", '*');
		PrintSeperator('*');

		InitGpuRuntime();
		PrintGpuRuntimeInfo();
	
		TestBandwidth();
		TestMemoryDump();
		TestKernel();
	
		ReleaseGpuRuntime();
	
		PrintSeperator('*');
		INFO("");
	}
	void TestBandwidth()
	{
		PrintSeperator('-');
		PrintHeader("device bandwidth test");

		BandwidthTest();
	}
	void TestMemoryDump()
	{
		PrintSeperator('-');
		PrintHeader("device memroy data test");

		float* d_a = nullptr;
		size_t sz, len;

		sz = LoadMemDev((void**)&d_a, get_debug_path() + "a.dat");
		len = sz / sizeof(float);
		LOG("read %d float from <a.dat>", len);
		LogDataDev<float>(d_a, len, "d_a");
	}
	void TestKernel()
	{
		PrintSeperator('-');
		PrintHeader("kernel launch test");

		float h_a[128], h_b[128], h_c[128];
		size_t sz = 128 * sizeof(float);
		for (uint32_t i = 0; i < 128; i++)
		{
			h_a[i] = 10.0f * i;
			h_b[i] = -0.1f * i;
			h_c[i] = 0;
		}
		float *d_a, *d_b, *d_c;
		d_a = (float*)DevMalloc(sz);
		d_b = (float*)DevMalloc(sz);
		d_c = (float*)DevMalloc(sz);
		MemCopyH2D(d_a, h_a, sz);
		MemCopyH2D(d_b, h_b, sz);
		MemCopyH2D(d_c, h_c, sz);

		GpuKernel* kernel;
		try 
		{
			kernel = new GpuKernel("VectorAdd");
		}
		catch (...)
		{
			LOG("Failed to create kernel");
			return;
		}
		kernel->SetArgs(d_a, d_b, d_c);
		kernel->SetGroupSize(32);
		kernel->SetGlobalSize(128);
		kernel->PrintWorkLoad();
		kernel->Launch();
		delete kernel;

		LogDataDev<float>(d_c, 128, "d_c");
	}
};
